package cn.aaalei.shorturl.service.impl;

import cn.aaalei.shorturl.mapper.UrlMapper;
import cn.aaalei.shorturl.pojo.UrlMapping;
import cn.aaalei.shorturl.service.ResolveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

@Service
public class ResolveServiceImpl implements ResolveService {

    @Autowired
    private UrlMapper urlMapper;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 从数据库查询真实地址 如果为空就返回null 不为空返回真实地址
     * @param hash
     * @return
     */
    @Override
    public String getTruthUrl(String hash) {

        //字符串的序列化器（这里只将key序列化--->AllUser）,为了在Redis管理工具更好看一点（AllUser不会出现前面的类似乱码的）
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        //查询Redis缓存
        String truthUrl = redisTemplate.opsForValue().get(hash);

        //解决高并发问题：双重监测锁
        if (truthUrl == null){
            synchronized (this){

                //查询Redis缓存
                truthUrl = redisTemplate.opsForValue().get(hash);

                if (truthUrl == null){
                    //缓存为空，查询数据库
                    UrlMapping urlMapping = urlMapper.selectUrlMapping(hash);
                    //数据库中不存在
                    if(urlMapping == null){
                        return null;
                    }
                    truthUrl = urlMapping.getFormerUrl();
                    System.out.println("查询的数据库...");

                    //把查询出来的数据放入到Redis中
                    redisTemplate.opsForValue().set(hash,truthUrl);
                }else {
                    System.out.println("查询的缓存...");
                }
            }
        }else {
            System.out.println("查询的缓存...");
        }

        return truthUrl;
    }
}